<?php

namespace app\common\service;

use app\common\service\Base;
use app\common\service\Order as OrderService;
use app\common\service\OrderMaterial as OrderMaterialService;
use app\common\service\StockLog as StockLogService;
use app\common\service\Stock as StockService;

class DistributingFeed extends Base
{
	/**
	 * 检测订单的某材料是否有采购在途
	 *
	 * @author KING
	 * @date 2020年6月2日
	 *
	 * @param integer $materialId
	 * @param integer $orderId
	 */
	public function checkIng($materialId, $orderId) {
		if (empty($materialId) || empty($orderId)) return false;
		$where = [
			['material_id', '=', $materialId],
			['order_id', '=', $orderId],
			['status', '<', 4],
		];
		return db('distributing_feed')->where($where)->count() ? true : false;
	}

	/**
	 * 获取在途采购量
	 *
	 * @author KING
	 * @date 2020年6月2日
	 *
	 * @param integer $materialId
	 * @param integer $orderId
	 */
	public function getIng($materialId, $orderId) {
		if (empty($materialId) || empty($orderId)) return 0;
		$where = [
			['material_id', '=', $materialId],
			['order_id', '=', $orderId],
			['status', '<', 4],
		];
		return db('distributing_feed')->where($where)->sum('need_feed_count');
	}

	/**
	 * 检测/使用库存，并自动发起补料单
	 *
	 * @author KING
	 * @date 2020年6月4日
	 *
	 * @param integer $materialId
	 * @param integer $orderId
	 * @param boolean $autoFeed		库存不够时，是否发起补料单
	 * @return array
	 * ret=-1	该订单物料已采购完成
	 * ret=-2	该订单物料已采购在途中
	 * ret=0	服务异常
	 * ret=1	已成功使用库存完成该物料的采购
	 * ret=2	已生成采购任务单，请前往补料区查看
	 * ret=3	需手动再次发起补料
	 */
	public function useStock($materialId, $orderId, $autoFeed=false) {
		$orderMaterialService = new OrderMaterialService();
		$orderService = new OrderService();
		$stockLogService = new StockLogService();
		$stockService = new StockService();

		$orderInfo = $orderService->getInfoById($orderId);
		$factoryId = arrayGet($orderInfo, 'factory_id', 0);
		$orderCount = arrayGet($orderInfo, 'quantity', 0);
		$clientOrdernum = arrayGet($orderInfo, 'client_ordernum', '');
		$orderMaterialInfo = $orderMaterialService->getInfoByOrderIdMaterialId($orderId, $materialId);
		$materialDosage = $orderMaterialInfo['material_dosage'];
		$sku = $orderMaterialInfo['mInfo']['material_sku'];//sku

		// 检测该物料是否已完成
		$useNum = $stockLogService->getUseNum($materialId, $orderId); // 已使用的量
		$materialDosageTotal = $orderCount*$materialDosage;	// 总用量
		if ($useNum >= $materialDosageTotal) {	// 已使用量 >= 总用量
			db('order_material')->where(['order_id' => $orderId, 'material_id' => $materialId])->update(['is_caigou_start' => 2,'caigou_finish_time'=>time(),]);
			return array("ret" => -1, "msg" => "该订单物料已采购完成！", "data" => ['info' => '']);
		}

		// 已使用量+采购在途数 > 总用量，则说明已有采购在途
		$ingCount = $this->getIng($materialId, $orderId);	// 采购在途数
		if ($autoFeed) {
			if ($ingCount && ($useNum+$ingCount) >= $materialDosageTotal) {
				db('order_material')->where(['order_id' => $orderId, 'material_id' => $materialId])->update(['is_caigou_start' => 1,'caigou_start_time' => time(),]);
				return array("ret" => -2, "msg" => "该订单物料已采购在途中！", "data" => ['info' => '']);
			}
		}

		$result = [];
		try {
			db()->startTrans();
			$stockInfo = db('stock')->where('material_id', $materialId)->findOrEmpty();
			if (!$stockInfo) {
				$stockInfo = [
					'material_id' => $materialId,
					'stock' => 0,
					'unit' => '',
					'create_time' => time(),
					'update_time' => time(),
				];
				$stockInfo['id'] = db('stock')->insertGetId($stockInfo);
			}
			$leftNum = $materialDosageTotal - $useNum - $ingCount;	// 本次请求需要的量

			// 优先使用辅料库存
			if ($leftNum > 0 && $stockInfo['stock'] > 0) {
				$subNum = min([$leftNum, $stockInfo['stock']]);
				$stockLogData = [
					'type' => 0,
					'stock_id' => $stockInfo['id'],
					'material_id' => $materialId,
					'factory_id' => $factoryId,
					'order_id' => $orderId,
					'client_ordernum' => $orderInfo['client_ordernum'],
					'sku' => $orderInfo['sku'],
					'left_num' => $stockInfo['stock']-$subNum,
					'operate_num' => $subNum,
					'remark' => '*使用库存',
					'create_time' => time(),
					'update_time' => time(),
				];
				db('stock_log')->insertGetId($stockLogData);

				// 更新库存
				db('stock')->where('id', $stockInfo['id'])->setDec('stock', $subNum);

				$leftNum = $leftNum - $subNum;
			}

			// 辅料库存不够时，使用通用料库存扣除
			if ($leftNum > 0) {
				$generalMaterialData = db('general_material')->where('id', 'in', db('general_material_sku')->where('sku', $sku)->column('general_material_id'))->order('stock desc')->findOrEmpty();
				if (!empty($generalMaterialData)) {
					$generalStock = $generalMaterialData['stock'];
					$generalId = $generalMaterialData['id'];
					$subNum = min([$leftNum, $generalStock]);

					$stockLogData = [
						'type' => 1,
						'stock_id' => $stockInfo['id'],//通用料不存在stock表id
						'material_id' => $materialId,
						'factory_id' => $factoryId,
						'order_id' => $orderId,
						'client_ordernum' => $orderInfo['client_ordernum'],
						'sku' => $orderInfo['sku'],
						'use_from_id' => 0,
						'left_num' => arrayGet($stockInfo, 'stock', 0) + $subNum,
						'operate_num' => $subNum,
						'unit_price' => 0,
						'amount' => 0,
						'remark' => '*通用库存转入',
						'create_time' => time(),
						'update_time' => time(),
					];
					db('stock_log')->insertGetId($stockLogData);

					$stockLogData = [
						'type' => 0,
						'stock_id' => $stockInfo['id'],//通用料不存在stock表id
						'material_id' => $materialId,
						'factory_id' => $factoryId,
						'order_id' => $orderId,
						'client_ordernum' => $orderInfo['client_ordernum'],
						'sku' => $orderInfo['sku'],
						'use_from_id' => 0,
						'left_num' => arrayGet($stockInfo, 'stock', 0),
						'operate_num' => $subNum,
						'unit_price' => 0,
						'amount' => 0,
						'remark' => '*通用库存转入后使用',
						'create_time' => time(),
						'update_time' => time(),
					];
					db('stock_log')->insertGetId($stockLogData);

					// 更新通用料剩余量
					$upData = [
						'stock' => $generalStock - $subNum,
						'update_time' => time(),
					];
					db('general_material')->where('id', $generalId)->update($upData);
					$leftNum = $leftNum - $subNum;
				}
			}

			if ($leftNum <= 0) {
				$result = array("ret" => 1, "msg" => "已成功使用库存完成该物料的采购！", "data" => ['info' => '']);
			} else {
				if ($autoFeed) {
					// 还需补量
					$dfData = [
						'factory_id' => $factoryId,
						'order_id' => $orderId,
						'client_ordernum' => $orderInfo['client_ordernum'],
						'material_id' => $materialId,
						'need_feed_count' => $leftNum,
						'status' => 1,
						'admin_id' => ADMIN_ID,
						'create_time' => time(),
						'update_time' => time(),
					];
					$dfId = db('distributing_feed')->insertGetId($dfData);
					//账号\订单号\型号\色号\颜色\采购量
					$result = array("ret" => 2, "msg" => "已生成采购任务单，请前往补料区查看 ID({$dfId})！", "data" => ['feed_id' => $dfId, 'info' => arrayGet(config('mimo.order_from'), $orderInfo['is_auto_import'], ''). " \ {$orderInfo['client_ordernum']} \ {$orderMaterialInfo['mInfo']['model']} \ {$orderMaterialInfo['mInfo']['colornum']} \ {$orderMaterialInfo['mInfo']['color']} \ {$leftNum}{$orderMaterialInfo['mInfo']['purchasing_unit']}"]);
				} else {
					$result = array("ret" => 3, "msg" => "需手动再次发起补料！", "data" => ['info' => ""]);
				}
			}

			db()->commit();
			return $result;
		} catch (\Exception $e) {
			db()->rollback();

			return array("ret" => 0, "msg" => "服务异常，请联系管理员！".$e->getMessage(), "data" => ['info' => '', 'line' => $e->getLine(), 'file' => $e->getFile()]);
		}
	}

	/**
	 * 指定使用多少库存量
	 *
	 * @author KING
	 * @date 2020年6月5日
	 *
	 * @param integer $materialId
	 * @param integer $orderId
	 * @param integer $useNum			使用量
	 */
	public function useStockNum($materialId, $orderId, $useNum) {
		$orderMaterialService = new OrderMaterialService();
		$orderService = new OrderService();
		$stockLogService = new StockLogService();
		$stockService = new StockService();

		try {
			$orderInfo = $orderService->getInfoById($orderId);
			$stockInfo = db('stock')->where([['material_id','eq',$materialId],['factory_id','eq',$orderInfo['factory_id']]])->order("stock desc")->findOrEmpty();
			if (!$stockInfo || $stockInfo && $stockInfo['stock'] < $useNum) {
				//throw new \Exception('材料['.getMaterialName($materialId).']库存不足(err:-2)');
			}
            if(empty($stockInfo)){
			    return '未找到对应厂的对应料库存数据，不做扣除与生成日志';
            }
			// 记录使用日志
			$stockLogData = [
				'type' => 0,
				'stock_id' => $stockInfo['id'],
				'material_id' => $materialId,
				'factory_id' => $orderInfo['factory_id'],
				'order_id' => $orderId,
				'client_ordernum' => $orderInfo['client_ordernum'],
				'sku' => $orderInfo['sku'],
				'left_num' => $stockInfo['stock'] - $useNum,
				'operate_num' => $useNum,
				'remark' => '使用库存',
				'create_time' => time(),
				'update_time' => time(),
			];
			db('stock_log')->insertGetId($stockLogData);
			// 更新库存数
			$res = db('stock')->where('id', $stockInfo['id'])->setDec('stock', $useNum);

		} catch (\Exception $e) {
			throw new \Exception($e->getMessage());
		}
	}

	/**
	 * 指定退回多少库存
	 *
	 * @author KING
	 * @date 2020年6月5日
	 *
	 * @param integer $materialId
	 * @param integer $orderId
	 * @param integer $num
	 */
	public function returnStockNum($materialId, $orderId, $num) {
		$orderMaterialService = new OrderMaterialService();
		$orderService = new OrderService();
		$stockLogService = new StockLogService();
		$stockService = new StockService();

		try {
			$orderInfo = $orderService->getInfoById($orderId);
			$factoryId = $orderInfo['factory_id'];
			$stockInfo = db('stock')->where('material_id', $materialId)->findOrEmpty();
			if (!$stockInfo) {
				$stockInfo = [
					'material_id' => $materialId,
					'stock' => $num,
					'unit' => '',
					'create_time' => time(),
					'update_time' => time(),
				];
				$stockInfo['id'] = db('stock')->insertGetId($stockInfo);
			} else {
				db('stock')->where('id', $stockInfo['id'])->setInc('stock', $num);
			}

			$stockLogData = [
				'type' => 2,
				'stock_id' => $stockInfo['id'],
				'material_id' => $materialId,
				'factory_id' => $factoryId,
				'order_id' => $orderId,
				'client_ordernum' => $orderInfo['client_ordernum'],
				'sku' => $orderInfo['sku'],
				'left_num' => $stockInfo['stock']+$num,
				'operate_num' => $num,
				'remark' => '退回库存',
				'create_time' => time(),
				'update_time' => time(),
			];
			db('stock_log')->insertGetId($stockLogData);

		} catch (\Exception $e) {
			throw new \Exception($e->getMessage());
		}
	}
}